/*******************************************************************************
  * 文件：OS_List.c
  * 作者：zyz
  * 版本：v2.0.1
  * 日期：2020-03-24
  * 说明：链表
*******************************************************************************/

/* 头文件 *********************************************************************/
#include "OS_List.h"

/* 宏定义 *********************************************************************/
/* 类型定义 *******************************************************************/
/* 变量定义 *******************************************************************/
/* 函数声明 *******************************************************************/
/* 函数定义 *******************************************************************/
/*******************************************************************************
  * 函数名: OS_ListInit
  * 功  能：初始化
  * 参  数：ListHandle_tps psList - 链表句柄
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void OS_ListInit(ListHandle_tps psList)
{
    // 头节点，向后指向尾节点，向前指向NULL
    psList->sListHead.psNext     = &(psList->sListTail);
    psList->sListHead.psPrevious = NULL;

    // 尾节点，向后指向NULL，向前指向头节点
    psList->sListTail.psNext     = NULL;
    psList->sListTail.psPrevious = &(psList->sListHead);

    // 设置头尾节点的节点值
    psList->sListHead.u16NodeValue = u16LIST_MIN_NODE_VALUE;
    psList->sListTail.u16NodeValue = u16LIST_MAX_NODE_VALUE;

    // 设置头尾节点所在链表
    psList->sListHead.psContainer = psList;
    psList->sListTail.psContainer = psList;

    // 设置头尾节点数据指针
    psList->sListHead.pvData = NULL;
    psList->sListTail.pvData = NULL;

    // 清零节点个数
    psList->u16NodesNum = 0;
}

/*******************************************************************************
  * 函数名: OS_ListInsertToHead
  * 功  能：插入新节点到链表头
  * 参  数：ListHandle_tps psList        - 链表句柄
  *         ListNodeHandle_tps psNewNode - 新节点句柄
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void OS_ListInsertToHead(ListHandle_tps psList, ListNodeHandle_tps psNewNode)
{
    // 确保不是头节点和尾节点
    if((psNewNode != &(psList->sListHead)) &&
       (psNewNode != &(psList->sListTail)))
    {
        // 新节点，向后指向头节点后一节点，向前指向头节点
        psNewNode->psNext = psList->sListHead.psNext;
        psNewNode->psPrevious = &(psList->sListHead);

        // 头节点后一节点，向前指向新节点
        psList->sListHead.psNext->psPrevious = psNewNode;

        // 头节点，向后指向新节点
        psList->sListHead.psNext = psNewNode;

        // 设置所在链表
        psNewNode->psContainer = psList;

        // 更新节点个数
        (psList->u16NodesNum)++;
    }
}

/*******************************************************************************
  * 函数名: OS_ListInsertToTail
  * 功  能：插入新节点到链表尾
  * 参  数：ListHandle_tps psList        - 链表句柄
  *         ListNodeHandle_tps psNewNode - 新节点句柄
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void OS_ListInsertToTail(ListHandle_tps psList, ListNodeHandle_tps psNewNode)
{
    // 确保不是头节点和尾节点
    if((psNewNode != &(psList->sListHead)) &&
       (psNewNode != &(psList->sListTail)))
    {
        // 新节点，向后指向尾节点，向前指向尾节点前一节点
        psNewNode->psNext = &(psList->sListTail);
        psNewNode->psPrevious = psList->sListTail.psPrevious;

        // 尾节点前一节点，向后指向新节点
        psList->sListTail.psPrevious->psNext = psNewNode;

        // 尾节点，向前指向新节点
        psList->sListTail.psPrevious = psNewNode;

        // 设置所在链表
        psNewNode->psContainer = psList;

        // 更新节点个数
        (psList->u16NodesNum)++;
    }
}

/*******************************************************************************
  * 函数名: OS_ListInsertByValue
  * 功  能：按照节点值插入新节点
  * 参  数：ListHandle_tps psList        - 链表句柄
  *         ListNodeHandle_tps psNewNode - 新节点句柄
  * 返回值：无
  * 说  明：从小到大的顺序
*******************************************************************************/
void OS_ListInsertByValue(ListHandle_tps psList, ListNodeHandle_tps psNewNode)
{
    ListNode_ts *psNodeIndex;

    // 确保不是头节点和尾节点
    if((psNewNode != &(psList->sListHead)) &&
       (psNewNode != &(psList->sListTail)))
    {
        // 查找合适位置
        for(psNodeIndex=psList->sListHead.psNext;
            psNodeIndex->u16NodeValue < psNewNode->u16NodeValue;
            psNodeIndex=psNodeIndex->psNext);

        // 在psNodeIndex节点前插入新节点
        // 新节点，向后指向psNodeIndex节点，向前指向psNodeIndex节点前一节点
        psNewNode->psNext = psNodeIndex;
        psNewNode->psPrevious = psNodeIndex->psPrevious;

        // psNodeIndex节点前一节点，向后指向新节点
        psNodeIndex->psPrevious->psNext = psNewNode;

        // psNodeIndex节点，向前指向新节点
        psNodeIndex->psPrevious = psNewNode;

        // 设置所在链表
        psNewNode->psContainer = psList;

        // 更新节点个数
        (psList->u16NodesNum)++;
    }
}

/*******************************************************************************
  * 函数名: OS_ListRemove
  * 功  能：移除节点
  * 参  数：ListNodeHandle_tps psNodeToRemove - 待移除节点句柄
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void OS_ListRemove(ListNodeHandle_tps psNodeToRemove)
{
    List_ts *psList;

    // 获取所在链表
    psList = psNodeToRemove->psContainer;

    // 确保不是头节点和尾节点，并且该节点属于链表
    if((psNodeToRemove != &(psList->sListHead)) &&
       (psNodeToRemove != &(psList->sListTail)))
    {
        // 待移除节点后一节点，向前指向待移除节点前一节点
        psNodeToRemove->psNext->psPrevious = psNodeToRemove->psPrevious;

        // 待移除节点前一节点，向后指向待移除节点后一节点
        psNodeToRemove->psPrevious->psNext = psNodeToRemove->psNext;

        // 设置所在链表
        psNodeToRemove->psContainer = NULL;

        // 更新节点个数
        (psList->u16NodesNum)--;
    }
}

/*******************************************************************************
  * 函数名: OS_ListGetNodesNum
  * 功  能：获取节点个数
  * 参  数：ListHandle_tps psList - 链表句柄
  * 返回值：节点个数
  * 说  明：无
*******************************************************************************/
U16 OS_ListGetNodesNum(ListHandle_tps psList)
{
    // 返回节点个数
    return (psList->u16NodesNum);
}

/***************************** 文件结束 ***************************************/
